<template>
	<view>
		<view @tap="reset" class="message-list">
			<uni-load-more :status="status" :contentText="{contentnomore: ' '}" />
			<view @tap.stop.prevent="reset(false)" class="message-item" v-for="item in messageList" :key="item.id" :id="'message-'+item.id">
				<xbc-message-time v-if="item.displayTime" :time="item.displayTime" />
				<template v-else>
					<!--系统、通知类消息-->
					<xbc-message v-if="['system', 'notice'].includes(item.type)" mode="custom">
						<xbc-message-system :message="item" />
					</xbc-message>
					<!--常规消息-->
					<xbc-message v-else :message="item" />
				</template>
			</view>
			<view class="xbc-editor-placeholder" :style="{height: placeholderHeight}"></view>
		</view>
		<xbc-editor @change="editorChange" @send="sendMessage" ref="editor" />
	</view>
</template>

<script>
import XBCIM from 'xbcim'
import IM from '@/common/xbcim'
import mixins from '@/mixins/index.js'
import { useEditor } from '@/hooks/useEditor'
const { scrollToBottom } = useEditor()

export default{
	mixins: [mixins],
	data(){
		return {
			scrollTop: 0,
			status: 'more',
			messageList: [],
			placeholderHeight: '61px',
			conversation: uni.getStorageSync('currentConversation'),
			state: {
				conversationId: '',
				conversationType: XBCIM.CONVERSATION_TYPE.SINGLE,
				nextMessageId: ''
			},
			user: {}
		}
	},
	onLoad(query){
		this.state.conversationId = query?.id || ''
		XBCIM.setConversationRead({
			conversationId: this.state.conversationId,
			conversationType: this.conversation.type
		})
		this.setTitle()
		this.getList()
		this.getUserProfile()
		
		// 监听
		XBCIM.on(XBCIM.EVENT.CONVERSATION_READ, this.listenConversationRead)
		XBCIM.on(XBCIM.EVENT.MESSAGE_READ, this.listenMessageRead)
		XBCIM.on(XBCIM.EVENT.MESSAGE_RECEIVED, this.listenMessageReceived)
	},
	onUnload(){
		XBCIM.off(XBCIM.EVENT.CONVERSATION_READ, this.listenConversationRead)
		XBCIM.off(XBCIM.EVENT.MESSAGE_READ, this.listenMessageRead)
		XBCIM.off(XBCIM.EVENT.MESSAGE_RECEIVED, this.listenMessageReceived)
	},
	onNavigationBarButtonTap(){
		uni.navigateTo({
			url: '/pages/contact/detail?userId='+this.conversation?.profile?.userId,
			events: {
				clearMessage() {
					this.messageList = []
				}
			}
		})
	},
	onPageScroll({ scrollTop }){
		this.scrollTop = scrollTop
		if(this.status == 'no-more') return
		if(!scrollTop) this.getList()
		this.status = scrollTop ? 'more' : 'loading'
	},
	methods: {
		// 设置标题
		setTitle() {
			uni.setNavigationBarTitle({
				title: this.conversation?.profile?.name
			})
		},
		// 发送消息回调
		sendMessage(message){
			this.messageList.push(message)
			scrollToBottom()
		},
		// 编辑器变化
		editorChange(height) {
			this.placeholderHeight = height
		},
		// 重置状态
		reset(isBottom = true) {
			this.$refs.editor?.reset(isBottom)
		},
		// 获取用户信息
		async getUserProfile(){
			this.user = await XBCIM.getUserProfile()
		},
		// 获取列表
		async getList() {
			try {
				const { list, nextMessageId } = await XBCIM.getMessageList(this.state)
				
				// 处理时间
				let newList = []
				list.forEach((item, index) => {
					const previousMessage = index > 0 ? list[index - 1] : null;
					if (previousMessage && item.createTime - previousMessage.createTime < 300) {
					} else {
						const [dateStr, timeStr] = XBCIM.date.toTimeStr(item.createTime)?.split(' ')
						const [year, month, day] = dateStr.split('-')
						const hourMinute = timeStr.split(':')[0] + ':' + timeStr.split(':')[1]
						newList.push({
							id: new Date().getTime() + '-' + index,
							displayTime: (XBCIM.date.isToday(item.createTime) ? '' : `${year}年${month}月${day}日` + '  ') + hourMinute
						})
					}
					newList.push(item)
				})
				
				// 1. 获取当前第一个元素的ID和位置
				const firstId = this.messageList[0]?.id
				
				// 赋值
				if (this.state.nextMessageId) {
					this.messageList.unshift(...newList)
					this.$nextTick(() => {
						if (firstId) {
							// 定位当前位置
							const query = uni.createSelectorQuery().in(this)
							query.select('#message-'+firstId).boundingClientRect(node=>{
								uni.pageScrollTo({
									duration: 0,
									scrollTop: node.top
								})
							}).exec()
						}
					})
				} else {
					this.messageList = newList
					setTimeout(() => {
						scrollToBottom()
					}, 20)
				}
				this.state.nextMessageId = nextMessageId
				this.status = nextMessageId ? 'more' : 'no-more'
			} catch (error) {
				console.log(error)
			}
		},
		// 监听会话已读
		listenConversationRead() {
			this.messageList.forEach((item) => {
				item.isRead = 1
			})
		},
		// 监听消息已读
		listenMessageRead(res) {
			const readMessageIds = res.list?.map((item) => item.id)
			this.messageList.forEach((item) => {
				if (readMessageIds.includes(item.id)) {
					item.isRead = 1
				}
			})
		},
		// 监听收到消息
		async listenMessageReceived(msg) {
			// @ts-ignore 当前会话时更新消息列表
			if (msg.conversationId == this.state.conversationId) {
				// 自动翻译
				const { autoTranslate, translateTo, userId } = this.user
				if(userId != msg.senderId && (autoTranslate > 0 && translateTo)){
					const translateMessage = await IM.translateMessage(msg)
					Object.assign(msg, translateMessage)
				}
				
				// 判断当前消息是否已经存在列表
				const index = this.messageList.findIndex(message => message.id == msg?.tempId)
				if(index >= 0){
					this.messageList.splice(index, 1, msg)
				}else{
					this.messageList.push(msg)
				}
				
				// @ts-ignore 上报已读回执：仅设置我收到的消息为已读，否则会导致已读数据不准确
				XBCIM.setMessageRead({ messageList: [msg] })
				setTimeout(() => {
					scrollToBottom()
				}, 20)
			}
		}
	}
}
</script>

<style lang="scss" scoped>
.message-list {
	min-height: 100vh;
	background-color: #f5f5f5;
	padding-bottom: env(safe-area-inset-bottom);
	padding-bottom: constant(safe-area-inset-bottom);

	.message-item {
		margin-bottom: 20rpx;
	}
}

.xbc-editor-placeholder {
	height: 120rpx;
	transition: height 0.3s ease;
	background-color: #f5f5f5;
}
</style>